package licode.unisop.unilite.utils;

import licode.unisop.unilite.result.UniException;
import licode.unisop.unilite.result.UniResult;
import licode.unisop.unilite.result.UniResultCode;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Supplier;

/**
 * 统一处理函数调用，获取业务的异常并返回
 *
 * @author WR
 */
@Slf4j
public class TryMethodCall {
    public static <R> R execFeign(Supplier<UniResult<R>> m) {
        UniResult<R> result;
        try {
            result = m.get();

            if (null == result) {
                throw new UniException(500, "无效接口");
            } else if (0 != result.getCode()) {
                throw new UniException(result.getCode(), result.getMessage());
            }
            return result.getData();
        } catch (Exception e) {
            throw new UniException(500, "调用接口异常");
        }
    }

    public static <R> UniResult<R> exec(R def, Supplier<R> call) {
        int code = 0;
        R retVal = def;
        String message = "success";
        StackTraceElement[] stackTraceElement;

        long startTime = System.currentTimeMillis();
        String tag = "";
        stackTraceElement = Thread.currentThread().getStackTrace();
        tag = stackTraceElement[2].getMethodName();

        try {
            retVal = call.get();
        } catch (UniException e) {
            code = e.getCode();
            message = e.getMessage();
            e.printStackTrace();
        } catch (Exception ee) {
            code = UniResultCode.SYSTEM_ERROR.code();
            message = UniResultCode.SYSTEM_ERROR.message();
            ee.printStackTrace();
        }

        startTime = System.currentTimeMillis() - startTime;
        log.debug("[{}]执行完成[{}ms], code: {}, message: {}, return: {}",
                tag, startTime, code, message, retVal);

        return UniResult.of(retVal, code, message);
    }
}
